package com.ruoyi.tengxun.service.impl;

import com.ruoyi.lock.config.TencentSmsConfig;
import com.ruoyi.tengxun.domain.SmsMessage;
import com.ruoyi.tengxun.service.ISmsService;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 腾讯云短信服务实现
 */
@Service
public class TencentSmsServiceImpl implements ISmsService {
    private static final Logger log = LoggerFactory.getLogger(TencentSmsServiceImpl.class);

    @Autowired
    private TencentSmsConfig smsConfig;

    /**
     * 发送短信
     *
     * @param message 短信消息
     * @return 是否发送成功
     */
    @Override
    public boolean sendSms(SmsMessage message) {
        try {
            // 实例化一个认证对象，入参需要传入腾讯云账户密钥对secretId，secretKey
            Credential cred = new Credential(smsConfig.getSecretId(), smsConfig.getSecretKey());
            
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            // 设置代理（无需要直接忽略）
            // httpProfile.setProxyHost("真实代理ip");
            // httpProfile.setProxyPort(真实代理端口);
            httpProfile.setReqMethod("POST");
            httpProfile.setConnTimeout(60);
            httpProfile.setEndpoint("sms.tencentcloudapi.com");

            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            
            // 实例化要请求产品的client对象，clientProfile是可选的
            SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
            
            // 实例化一个请求对象,每个接口都会对应一个request对象
            SendSmsRequest req = new SendSmsRequest();
            
            // 设置短信应用ID
            req.setSmsSdkAppId(smsConfig.getSdkAppId());
            
            // 设置短信签名
            req.setSignName(smsConfig.getSignName());
            
            // 设置国际电话区号
            String[] phoneNumberSet = {"+".concat(message.getRegion() != null ? message.getRegion() : smsConfig.getRegion()).concat(message.getPhoneNumber())};
            req.setPhoneNumberSet(phoneNumberSet);
            
            // 设置模板ID
            req.setTemplateId(getTemplateId(message.getSmsType()));
            
            // 设置模板参数
            String[] templateParamSet = formatTemplateParams(message.getSmsType(), message.getParams());
            req.setTemplateParamSet(templateParamSet);
            
            // 发送短信
            SendSmsResponse response = client.SendSms(req);
            
            log.info("短信发送结果: {}", SendSmsResponse.toJsonString(response));
            return true;
        } catch (TencentCloudSDKException e) {
            log.error("发送短信失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 发送验证码
     *
     * @param phoneNumber 手机号
     * @param code        验证码
     * @return 是否发送成功
     */
    @Override
    public boolean sendVerificationCode(String phoneNumber, String code) {
        SmsMessage message = new SmsMessage()
                .setPhoneNumber(phoneNumber)
                .setSmsType(SmsMessage.SmsType.VERIFICATION_CODE);
        
        Map<String, String> params = new HashMap<>();
        params.put("1", code);
        message.setParams(params);
        
        return sendSms(message);
    }

    /**
     * 发送密码开通通知
     *
     * @param phoneNumber 手机号
     * @return 是否发送成功
     */
    @Override
    public boolean sendPasswordOpenNotification(String phoneNumber) {
        SmsMessage message = new SmsMessage()
                .setPhoneNumber(phoneNumber)
                .setSmsType(SmsMessage.SmsType.PASSWORD_OPEN);
        
        return sendSms(message);
    }

    /**
     * 发送密码修改通知
     *
     * @param phoneNumber 手机号
     * @return 是否发送成功
     */
    @Override
    public boolean sendPasswordModifyNotification(String phoneNumber) {
        SmsMessage message = new SmsMessage()
                .setPhoneNumber(phoneNumber)
                .setSmsType(SmsMessage.SmsType.PASSWORD_MODIFY);
        
        return sendSms(message);
    }

    /**
     * 发送续期通知
     *
     * @param phoneNumber 手机号
     * @return 是否发送成功
     */
    @Override
    public boolean sendRenewalNotification(String phoneNumber) {
        SmsMessage message = new SmsMessage()
                .setPhoneNumber(phoneNumber)
                .setSmsType(SmsMessage.SmsType.RENEWAL);
        
        return sendSms(message);
    }

    /**
     * 根据短信类型获取模板ID
     *
     * @param smsType 短信类型
     * @return 模板ID
     */
    private String getTemplateId(SmsMessage.SmsType smsType) {
        switch (smsType) {
            case VERIFICATION_CODE:
                return smsConfig.getLoginTemplateId();
            case PASSWORD_OPEN:
                return smsConfig.getPasswordOpenTemplateId();
            case PASSWORD_MODIFY:
                return smsConfig.getPasswordModifyTemplateId();
            case RENEWAL:
                return smsConfig.getRenewalTemplateId();
            default:
                throw new IllegalArgumentException("无效的短信类型: " + smsType);
        }
    }

    /**
     * 格式化模板参数
     *
     * @param smsType 短信类型
     * @param params  参数Map
     * @return 参数数组
     */
    private String[] formatTemplateParams(SmsMessage.SmsType smsType, Map<String, String> params) {
        if (params == null) {
            params = new HashMap<>();
        }
        
        switch (smsType) {
            case VERIFICATION_CODE:
                // 验证码参数
                return new String[]{params.getOrDefault("1", "")};
            case PASSWORD_OPEN:
            case PASSWORD_MODIFY:
            case RENEWAL:
                // 这些通知类型不需要参数
                return new String[]{};
            default:
                throw new IllegalArgumentException("无效的短信类型: " + smsType);
        }
    }
} 